package com.itqf.captcha;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

/**
 * projectName: gpshop
 *
 * @author: 赵伟风
 * time: 2021/7/20 11:05
 * description:验证码存储和管理工具类
 *
 * 工具类: 目标是简化使用者!
 *         工具类尽量使用static修饰!
 *
 *         工具类要多使用重载!
 *
 * 问题:  使用验证码作为map的key!很容易出现一种情况! 不同的用户随机到相同的验证码!
 *        后面随机的用户,无法进行验证码存储!
 */
public class CaptchaManager {

    /**
     * 缓存的容器
     */
    public static Map<String,CaptchaItem> codeCache = new HashMap<>();

    /**
     * 默认缓存的时间 单位:分钟
     */
    public static final  Integer DEFAULT_TIME =3;


    /**
     * 将验证码和指定的缓存时间存到缓存容器中!
     * @param code 缓存的验证码
     * @param time 缓存时间,如果未指定,指定默认时间即可!
     * @return boolean true 代表添加成功  false代表添加失败
     */
    public static boolean addToCache(String code,Integer time){

        //1.读或者取 清空下缓存
        clearCache();
        //2.判断是否存在code对应的缓存
        if (codeCache.get(code) != null) {
            //存在缓存 没有过期的缓存
            return false;
        }
        //3.不存在或者存在已经过期,我们添加code缓存
        CaptchaItem item =  new CaptchaItem();
        item.setCode(code);
        if (time == null) {
            time = DEFAULT_TIME;
        }
        item.setExpireTime(LocalDateTime.now().plusMinutes(time));
        codeCache.put(code,item);

        return true;
    }

    /**
     * 从验证码缓存容器中,获取验证码是否存在,存在是否过期!
     * @param code 判断是否存在并且是否过期的验证码!
     * @return boolean true 存在,并且没有过期!  false:不存在 或者 存在过期!
     */
    public static  boolean getFromCache(String code){
        //1.清空缓存
        clearCache();

        //2.获取
        if (!codeCache.containsKey(code)) {

            return false;
        }

        return true;
    }


    /**
     * 清空过期的缓存code!
     * 注意: 程序中没有添加定时任务等清空调用!
     *       需要在获取或者添加的时候,进行清空缓存调用!
     */
    public static  void clearCache(){

        //定义过期的key的集合
        Set<String> keys = new HashSet<>();

        //遍历map
        for (Map.Entry<String, CaptchaItem> itemEntry : codeCache.entrySet()) {
            if (itemEntry.getValue().getExpireTime().isBefore(LocalDateTime.now())) {
                //过期
                keys.add(itemEntry.getKey());
            }
        }

        //移除即可!
        for (String code : keys) {
            //移除过期的code
            codeCache.remove(code);
        }

    }



}
